bitkeeper revision 1.1236.1.202 (424f0f028PbpGAMdxoGmEzj3n3SehQ)
authorcl349@firebug.cl.cam.ac.uk[cl349] <cl349@firebug.cl.cam.ac.uk[cl349]>
Sat, 2 Apr 2005 21:30:42 +0000 (21:30 +0000)
committercl349@firebug.cl.cam.ac.uk[cl349] <cl349@firebug.cl.cam.ac.uk[cl349]>
Sat, 2 Apr 2005 21:30:42 +0000 (21:30 +0000)
Merge 2.0-testing change:
  From: YAMAMOTO Takashi <yamt@mwd.biglobe.ne.jp>
  Add support to domain0 builder to load a (Net)BSD symtab for domain0.

Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
1  2 
xen/common/elf.c
xen/include/xen/elf.h
xen/include/xen/sched.h

index 3ee170b453f9ac086f5be72bdff8d181886c9c2b,7feb9095dbf57d5ddcbcd9f0adaead6542bf531e..1302acfdea499482dc88a773ef23b96f3582b77e
@@@ -118,6 -122,13 +118,10 @@@ int parseelfimage(char *elfbase
      {
          if ( (p = strstr(guestinfo, "VIRT_BASE=")) != NULL )
              dsi->v_start = simple_strtoul(p+10, &p, 0);
 -        
 -        if ( (p = strstr(guestinfo, "PT_MODE_WRITABLE")) != NULL )
 -            dsi->use_writable_pagetables = 1;
+         if ( (p = strstr(guestinfo, "BSD_SYMTAB")) != NULL )
+             dsi->load_bsd_symtab = 1;
      }
  
      dsi->v_kernstart = kernstart;
@@@ -149,12 -162,96 +155,106 @@@ int loadelfimage(char *elfbase
      return 0;
  }
  
+ #define ELFROUND (ELFSIZE / 8)
+ int loadelfsymtab(char *elfbase, int doload, struct domain_setup_info *dsi)
+ {
+     Elf_Ehdr *ehdr = (Elf_Ehdr *)elfbase, *sym_ehdr;
+     Elf_Shdr *shdr;
+     unsigned long maxva, symva;
+     char *p;
+     int h, i;
+     maxva = (dsi->v_kernend + ELFROUND - 1) & ~(ELFROUND - 1);
+     symva = maxva;
+     maxva += sizeof(int);
+     dsi->symtab_addr = maxva;
+     dsi->symtab_len = 0;
+     maxva += sizeof(Elf_Ehdr) + ehdr->e_shnum * sizeof(Elf_Shdr);
+     maxva = (maxva + ELFROUND - 1) & ~(ELFROUND - 1);
+     if (doload) {
+       p = (void *)symva;
+       shdr = (Elf_Shdr *)(p + sizeof(int) + sizeof(Elf_Ehdr));
+       memcpy(shdr, elfbase + ehdr->e_shoff, ehdr->e_shnum * sizeof(Elf_Shdr));
+     } else {
+       shdr = (Elf_Shdr *)(elfbase + ehdr->e_shoff);
+       p = NULL; /* XXX: gcc */
+     }
+     for ( h = 0; h < ehdr->e_shnum; h++ ) 
+     {
+         if ( shdr[h].sh_type == SHT_STRTAB )
+         {
+             /* Look for a strtab @i linked to symtab @h. */
+             for ( i = 0; i < ehdr->e_shnum; i++ )
+                 if ( (shdr[i].sh_type == SHT_SYMTAB) &&
+                      (shdr[i].sh_link == h) )
+                     break;
+             /* Skip symtab @h if we found no corresponding strtab @i. */
+             if ( i == ehdr->e_shnum )
+             {
+               if (doload) {
+                   shdr[h].sh_offset = 0;
+               }
+                 continue;
+             }
+         }
+         if ( (shdr[h].sh_type == SHT_STRTAB) ||
+              (shdr[h].sh_type == SHT_SYMTAB) )
+         {
+           if (doload) {
+               memcpy((void *)maxva, elfbase + shdr[h].sh_offset,
+                   shdr[h].sh_size);
+               /* Mangled to be based on ELF header location. */
+               shdr[h].sh_offset = maxva - dsi->symtab_addr;
+           }
+           dsi->symtab_len += shdr[h].sh_size;
+           maxva += shdr[h].sh_size;
+           maxva = (maxva + ELFROUND - 1) & ~(ELFROUND - 1);
+         }
+         if (doload) {
+           shdr[h].sh_name = 0;  /* Name is NULL. */
+       }
+     }
+     if ( dsi->symtab_len == 0 )
+     {
+         dsi->symtab_addr = 0;
+         goto out;
+     }
+     if (doload) {
+       *(int *)p = maxva - dsi->symtab_addr;
+       sym_ehdr = (Elf_Ehdr *)(p + sizeof(int));
+       memcpy(sym_ehdr, ehdr, sizeof(Elf_Ehdr));
+       sym_ehdr->e_phoff = 0;
+       sym_ehdr->e_shoff = sizeof(Elf_Ehdr);
+       sym_ehdr->e_phentsize = 0;
+       sym_ehdr->e_phnum = 0;
+       sym_ehdr->e_shstrndx = SHN_UNDEF;
+     }
+ #define round_pgup(_p)    (((_p)+(PAGE_SIZE-1))&PAGE_MASK) /* XXX */
+     dsi->symtab_len = maxva - dsi->symtab_addr;
+     dsi->v_end = round_pgup(maxva);
+  out:
+     return 0;
+ }
++
 +/*
 + * Local variables:
 + * mode: C
 + * c-set-style: "BSD"
 + * c-basic-offset: 4
 + * tab-width: 4
 + * indent-tabs-mode: nil
 + * End:
 + */
index 227fa3ade1aa9ff8090277f0140babb8d76076d4,3a62173b1ee2bf9d3c9436e8335f7d3091f9c040..0b98390ed591b68e745e818b9d3d5d2582c33949
@@@ -527,10 -526,7 +527,11 @@@ typedef struct 
  
  struct domain_setup_info;
  extern int loadelfimage(char *);
+ extern int loadelfsymtab(char *, int, struct domain_setup_info *);
  extern int parseelfimage(char *, unsigned long, struct domain_setup_info *);
  
 +#ifdef Elf_Ehdr
 +extern int elf_sanity_check(Elf_Ehdr *ehdr);
 +#endif
 +
  #endif /* __XEN_ELF_H__ */
index 670b891f59617a85d1d1ca1508228ac91ff4a105,4b7e7080c851e89fbcbb7068612f9e12e1f1fd84..ac783669d15cd3e88104d99885297ff15b4f0b8c
@@@ -155,6 -123,12 +156,11 @@@ struct domain_setup_inf
      unsigned long v_kernstart;
      unsigned long v_kernend;
      unsigned long v_kernentry;
 -    unsigned int use_writable_pagetables;
+     unsigned int load_bsd_symtab;
+     unsigned long symtab_addr;
+     unsigned long symtab_len;
  };
  
  #include <asm/uaccess.h> /* for KERNEL_DS */